﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

// The namespaces that need to be added manually, apart from the ones that come with the new Windows Form template
using System.IO;
using System.Xml;
using System.Xml.Linq;

namespace XmlFormattingTest
{
    /// <summary>
    /// The form that enables us to demonstrate the different ways to properly format XML
    /// The input is read from input.xml in the current directory, displayed in the left-hand textbox
    /// and then the result is displayed in the other textbox. A radiobutton list allows chossing
    /// the method
    /// </summary>
    public partial class XmlFormattingTestForm : Form
    {
        public const string INPUT_PATH = "input.xml";
        public const string OUTPUT_PATH = "output.xml";
        
        public XmlFormattingTestForm()
        {
            InitializeComponent();
        }

        #region Implementations of the different processing methods 

        private void process_NoWriter()
        {
            XmlDocument xml = new XmlDocument();
            xml.Load(INPUT_PATH);
            // ... XML processing code
            xml.Save(OUTPUT_PATH);
        }

        private void process_Writer()
        {
            XmlDocument xml = new XmlDocument();
            xml.Load(INPUT_PATH);
            // ... XML processing code
            XmlWriter writer = XmlWriter.Create(OUTPUT_PATH);
            xml.Save(writer);

            writer.Close();
        }

        private void process_Indent()
        {
            XmlDocument xml = new XmlDocument();
            xml.Load(INPUT_PATH);
            // ... XML processing code
            XmlWriterSettings writerSettings = new XmlWriterSettings();
            writerSettings.Indent = true;
            XmlWriter writer = XmlWriter.Create(OUTPUT_PATH, writerSettings);
            xml.Save(writer);

            writer.Close();
        }

        private void process_XElement()
        {
            XDocument xDoc = XDocument.Load(INPUT_PATH);
            // ... XML processing code
            String xmlString = xDoc.Declaration.ToString() + Environment.NewLine + xDoc.ToString();

            txtOutput.Text = xmlString; // operation is in-memory - we can show the string directly in the output box 
        }

        private void process_Binary()
        {
            XDocument xDoc = XDocument.Load(INPUT_PATH);
            // ... XML processing code
            String xmlString = xDoc.Declaration.ToString() + Environment.NewLine + xDoc.ToString();
            byte[] xmlBytes = Encoding.UTF8.GetBytes(xmlString);

            txtOutput.Text = Encoding.UTF8.GetString(xmlBytes);
        }

        #endregion

        #region Generic application code
        // code needed to connect the UI to the formatting implementations

        // load the input
        private void XmlFormattingTestForm_Load(object sender, EventArgs e)
        {
            StreamReader reader = new StreamReader(INPUT_PATH);
            txtInput.Text = reader.ReadToEnd();
            txtInput.Select(0, 0);
            btnProcess.Focus();
        }

        // execute routine depending on the selection in the radiobutton list
        private void btnProcess_Click(object sender, EventArgs e)
        {
            if (rbtSimple.Checked)
            {
                process_NoWriter();
                loadOutput();
            }
            if (rbtWriterNoSettings.Checked)
            {
                process_Writer();
                loadOutput();
            }
            if (rbtIndent.Checked)
            {
                process_Indent();
                loadOutput();
            }
            // this following two don't save the output to a file, instead they show it directly in the output box
            if (rbtXElement.Checked)
            {
                process_XElement(); 
            }
            if (rbtBinary.Checked)
            {
                process_Binary();
            }

            lblDone.Visible = true;
        }

        private void loadOutput()
        {
            StreamReader reader = new StreamReader(OUTPUT_PATH);
            txtOutput.Text = reader.ReadToEnd();
        }

        private void rbt_CheckedChanged(object sender, EventArgs e)
        {
            lblDone.Visible = false;
        }

        #endregion
    }
}
